#include <func.h>
#include <mysql/mysql.h>
#include <stdio.h>
#include "DB.h"
#include "Crypto.h"

// 返回用户的id, 用户不存在返回0
int username_exist(MYSQL* mysql, const char* username)
{
    char stmt[1024];
    sprintf(stmt, "SELECT id FROM users WHERE username = '%s'", username);
    printf("SQL: %s\n", stmt);
    if (mysql_query(mysql, stmt)) {
        fprintf(stderr, "mysql_query(): %s\n", mysql_error(mysql));
        return 0;  // 表示发生错误
    }
    MYSQL_RES* result = mysql_store_result(mysql);
    uint64_t rows = mysql_num_rows(result);
    if (rows == 0) {
        mysql_free_result(result);   // 释放结果集
        return 0;
    }
    MYSQL_ROW row = mysql_fetch_row(result);
    mysql_free_result(result);
    return atoi(row[0]);
}

// 判断客户端发送的密码是否正确
int verify_password(MYSQL* mysql, const char* username, const char* input_password)
{
    // 1. 检查用户名是否存在
    int user_id = username_exist(mysql, username);
    if (user_id == 0) {
        return 0; // 用户不存在
    }

    // 2. 查询用户的盐值和密码哈希
    char stmt[1024];
    snprintf(stmt, sizeof(stmt),
             "SELECT salt, passwd FROM users WHERE id = %d", user_id);

    if (mysql_query(mysql, stmt)) {
        fprintf(stderr, "mysql_query(): %s\n", mysql_error(mysql));
        return 0;
    }

    MYSQL_RES* result = mysql_store_result(mysql);
    if (!result || mysql_num_rows(result) == 0) {
        mysql_free_result(result);
        return 0;
    }

    MYSQL_ROW row = mysql_fetch_row(result);
    const char* stored_salt = row[0];
    const char* stored_hash = row[1];
    mysql_free_result(result);

    // 3. 使用相同的盐值对输入密码进行哈希处理
    char computed_hash[65] = ""; // SHA-256 哈希长度为 64 字节，转换为十六进制后为 64 * 2 = 128 字符
    sha256_passwd(stored_salt, input_password, computed_hash);

    // 4. 比较哈希值
    if (strcmp(computed_hash, stored_hash) == 0) {
        return 1; // 密码正确
    } else {
        return 0; // 密码错误
    }
}


int username_register(MYSQL* mysql, const char* username, const char* passwd)
{
    char salt[21] = "";
    generate_salt(salt, 20); // 随机生成盐值
    char hashcode[65] = "";
    sha256_passwd(salt, passwd, hashcode);  // 对密码进行哈希
    char stmt[1024]; 
    sprintf(stmt, "INSERT INTO users (username, salt, passwd, create_time) ,"
            "VALUES ('%s', '%s', '%s', now())",
            username, salt, hashcode);
    printf("SQL: %s\n", stmt);
    if (mysql_query(mysql, stmt)) {
        fprintf(stderr, "mysql_query(): %s\n", mysql_error(mysql));
        return -1;
    }
    uint64_t rows = mysql_affected_rows(mysql);
    return rows == 1;
}

int path_exist(MYSQL* mysql, const char* path)
{
    char stmt[1024];
    sprintf(stmt, "SELECT id FROM paths WHERE path = '%s'", path);
    printf("SQL: %s\n", stmt);
    if (mysql_query(mysql, stmt)) {
        // 发生错误
        fprintf(stderr, "mysql_query(): %s\n", mysql_error(mysql));
        return 0;  
    }
    MYSQL_RES* result = mysql_store_result(mysql);
    uint64_t rows = mysql_num_rows(result);
    if (rows == 0) {
        mysql_free_result(result);   // 释放结果集
        return 0;
    }
    MYSQL_ROW row = mysql_fetch_row(result);
    mysql_free_result(result);
    return atoi(row[0]);
}

int path_create(MYSQL* mysql, int user_id, const char* path, char type)
{
    char stmt[1024]; 
    sprintf(stmt, "INSERT INTO paths (user_id, path, type, create_time) VALUES ('%d', '%s', '%c', now())",
            user_id, path, type);
    printf("SQL: %s\n", stmt);
    printf("path_create success\n");
    if (mysql_query(mysql, stmt)) {
        // 发生错误
        fprintf(stderr, "mysql_query(): %s\n", mysql_error(mysql));
        return 0;
    }
    uint64_t rows = mysql_affected_rows(mysql);
    return rows == 1;
}

int file_exist(MYSQL* mysql, const char* sha256sum)
{
    //通过查看哈希值是否存在，确认文件是否已上传
    char stmt[1024];
    sprintf(stmt, "SELECT id FROM files WHERE sha256sum = '%s'", sha256sum);
    printf("SQL: %s\n", stmt);
    if (mysql_query(mysql, stmt)) {
        // 发生错误
        fprintf(stderr, "mysql_query(): %s\n", mysql_error(mysql));
        return 0;  
    }
    MYSQL_RES* result = mysql_store_result(mysql);
    uint64_t rows = mysql_num_rows(result);
    if (rows == 0) {
        mysql_free_result(result);   // 释放结果集
        return 0;
    }
    MYSQL_ROW row = mysql_fetch_row(result);
    mysql_free_result(result);
    return atoi(row[0]);
}

int file_create(MYSQL* mysql, const char* sha256sum, long size)
{
    char stmt[1024]; 
    sprintf(stmt, "INSERT INTO files (sha256sum, size) VALUES ('%s', %ld)",
            sha256sum, size);
    printf("SQL: %s\n", stmt);
    if (mysql_query(mysql, stmt)) {
        // 发生错误
        fprintf(stderr, "mysql_query(): %s\n", mysql_error(mysql));
        return 0;
    }
    uint64_t rows = mysql_affected_rows(mysql);
    return rows == 1;
}

int pathtofile_create(MYSQL* mysql, int path_id, int file_id, int sequence)
{
    char stmt[1024]; 
    sprintf(stmt, "INSERT INTO path_to_file (path_id, file_id, sequence) VALUES (%d, %d, %d)",
            path_id, file_id, sequence);
    printf("SQL: %s\n", stmt);
    if (mysql_query(mysql, stmt)) {
        // 发生错误
        fprintf(stderr, "mysql_query(): %s\n", mysql_error(mysql));
        return 0;
    }
    uint64_t rows = mysql_affected_rows(mysql);
    return rows == 1;

}
